﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;
using System.ServiceModel;
using System.ServiceModel.Description;

using PEMS.Common;


namespace PEMS.Client
{
    public sealed class ClientController
    {
        private PemsService.PemsServiceClient _pemsClient;
//        public N_1 kliensID { get; set; }
        public N_FelhasznaloTipus kliensID { get; set; }
        private static ClientController _instance = null;
        private static readonly Object _lock = new Object();
        private bool _timer_seged=true;

        public static ClientController instance
        {
            get
            { 
                lock (_lock)
                {
                    if (_instance == null)
                    {
                        _instance = new ClientController();
                    }
                }
                return _instance;
            }
        }
        

        /// <summary>
        /// Konstruktor
        /// </summary>
        private ClientController()
        {
            Log.logToFile("ClientController created!",false);

//            kliensID = new N_1();
            kliensID = new N_FelhasznaloTipus();
            kliensID.bools.Add("belepve",false);
            kliensID.strings.Add("id","");
            kliensID.strings.Add("jelszo","");
            kliensID.strings.Add("userNev","");
            kliensID.strings.Add("ip","");
        }

        /// <summary>
        /// a ping küldése, az eredménnyel visszatér
        /// ez azért kell, hogy a session élve maradjon
        /// </summary>
        public bool ping()
        {
            bool ret=true;
            try
            {
                _pemsClient.ping();
            }
            catch
            {
                reset();
                if (_timer_seged)
                {
                    _timer_seged = false;
                }
                ret = false;
            }
            return ret;
        }
        
        // <summary>
        /// a hálózat megnyitása
        /// </summary>
        public bool open()
        {
            _pemsClient = new PemsService.PemsServiceClient();

            _pemsClient.ClientCredentials.Windows.ClientCredential.UserName = Properties.Settings.Default.windowsServer_username;
            _pemsClient.ClientCredentials.Windows.ClientCredential.Password = Properties.Settings.Default.windowsServer_password;
            //_pemsClient.ClientCredentials.Windows.ClientCredential.Domain = "windowsdomain";
            try
            {
                _pemsClient.Open();
                return true;
            }
            catch (Exception e)
            {
                Console.WriteLine("\n\nException: " + e.Message);
                return false;
            }
        }

        /// <summary>
        /// kijelentkezés
        /// </summary>
        public void logoff()
        {
            reset();
            _pemsClient.stop();
        }

        /// <summary>
        /// bejelentkezés
        /// </summary>
        public bool logon(string u, string p){
            
            bool ret = false;
            
            kliensID.strings["userNev"] = u;
            kliensID.strings["jelszo"] = p;

            //elküldjük hálózaton és vissza is kapjuk
            kliensID = _pemsClient.auth(kliensID);

            if (kliensID.bools["belepve"])
            {
                _timer_seged = true;
                ret = true;
            }
            else
                _pemsClient.stop();
            
            return ret;
        }

        /// <summary>
        /// a bejelentkezéshez szükséges dolgok nullázása
        /// </summary>
        private void reset(){
            kliensID.bools["belepve"] = false;
            kliensID.strings["id"] = "";
            kliensID.strings["jelszo"] = "";
            kliensID.strings["userNev"] = "";
            kliensID.strings["ip"] = "";
        }
        
        /// <summary>
        /// Felhasználói jogosultság lekérdezése
        /// userName alapján
        /// </summary>
        public UserTypeEnum getFelhasznaloJogosultsag(string userName)
        {
            N_FelhasznaloTipus komm = new N_FelhasznaloTipus();
            komm.strings.Add("userName", userName);

            komm = _pemsClient.getFelhasznaloJogosultsag(komm);
            return komm.jogosultsag;
        }

        /// <summary>
        /// Felhasználó hozzáadása
        /// név, teljes név, jelszó, jogosultság alapján
        /// </summary>
        public bool felhasznaloHozzaadasa(string userName, string fullName, string password, UserTypeEnum jogosultsag)
        {
            N_FelhasznaloTipus komm = new N_FelhasznaloTipus();
            komm.bools.Add("hozzaadva", false);
            komm.strings.Add("userName", userName);
            komm.strings.Add("fullName", fullName);
            komm.strings.Add("password", password);
            komm.jogosultsag = jogosultsag;

            komm = _pemsClient.felhasznaloHozzaadasa(komm);
            return komm.bools["hozzaadva"];
        }

        /// <summary>
        /// Új tárgy hozzáadása
        /// id és megnevezés alapján
        /// </summary>
        public bool targyHozzaadasa(string id, string megnevezes)
        {
            N_1 komm = new N_1();
            komm.bools.Add("hozzaadva", false);
            komm.strings.Add("id", id);
            komm.strings.Add("megnevezes", megnevezes);

            komm = _pemsClient.targyHozzaadasa(komm);
            return komm.bools["hozzaadva"];
        }

        /// <summary>
        /// Kurzus meghirdetese
        /// id, megnevezes, targy, oktato alapján
        /// </summary>
        public bool kurzusMeghirdetese(string felev, string kurzus, string megnevezes, string targy, string oktato)
        {
            N_1 komm = new N_1();
            komm.bools.Add("hozzaadva", false);
            komm.strings.Add("felev", felev);
            komm.strings.Add("megnevezes", megnevezes);
            komm.strings.Add("kurzus", kurzus);
            komm.strings.Add("targy", targy);
            komm.strings.Add("oktato", oktato);

            komm = _pemsClient.kurzusMeghirdetese(komm);
            return komm.bools["hozzaadva"];
        }

        /// <summary>
        /// Vizsga meghirdetese
        /// félév, kurzus, időpont és max létszám alapján
        /// </summary>
        public bool vizsgaMeghirdetese(string felev, string kurzus, DateTime idopont, int maxLetszam)
        {
            N_Datum komm = new N_Datum();
            komm.bools.Add("hozzaadva", false);
            komm.strings.Add("felev", felev);
            komm.strings.Add("kurzus", kurzus);
            komm.kezdoDatum = idopont;
            komm.ints["maxLetszam"] = maxLetszam;

            komm = _pemsClient.vizsgaMeghirdetese(komm);
            return komm.bools["hozzaadva"];
        }

        /// <summary>
        /// Hallgatók listája
        /// a paraméter dönti el, hogy csak az aktív hallgatók kerülnek-e listázásra vagy az összes
        /// </summary>
        public List<string> getHallgatoLista(bool csakAktiv, string kurzus, string vizsgaidopontID, string userName, bool alairasLista = false)
        {

            N_FelhasznaloTipus komm = new N_FelhasznaloTipus();
            komm.strings.Add("userName", userName);                 // ki indította el a lekérdezést
            komm.strings.Add("felev", getAktualisFelev());          // aktuális félév beállítása, csak ez érdekel minket
            komm.strings.Add("kurzus", kurzus);                     // milyen kurzusra, ha üres akkor minden kurzust végignéz
            komm.strings.Add("vizsgaidopontID", vizsgaidopontID);   // milyen kurzusra, ha üres akkor minden kurzust végignéz
            komm.bools.Add("alairasLista", alairasLista);           // aláírás beállításnál készülő listához segédváltozó
            komm.bools.Add("csakAktiv", csakAktiv);                 // csak az aktív hallgatókat listázza vagy mindenkit aki szerepel a rendszerben
            komm.jogosultsag = UserTypeEnum.hallgato;               // csak a hallgatókat akarjuk lekérdezni
            
            komm = _pemsClient.getFelhasznaloLista(komm);
            return komm.row;
        }

        /// <summary>
        /// Oktatók listája
        /// a paraméter dönti el, hogy csak az aktív hallgatók kerülnek-e listázásra vagy az összes
        /// </summary>
        public List<string> getOktatoLista(bool csakAktiv)
        {

            N_FelhasznaloTipus komm = new N_FelhasznaloTipus();
            komm.bools.Add("csakAktiv", csakAktiv);
            komm.jogosultsag = UserTypeEnum.oktato;

            komm = _pemsClient.getFelhasznaloLista(komm);
            return komm.row;
        }

        /// <summary>
        /// Félév meglétének ellenőrzése
        /// ehhez meg kell adni a kérdéses félévet
        /// </summary>
        public bool felevLetezik(string felev)
        {
            N_1 komm = new N_1();
            komm.strings.Add("felev", felev);
            komm.bools.Add("letezik", false);

            komm = _pemsClient.felevLetezik(komm);
            return komm.bools["letezik"];
        }

        /// <summary>
        /// Tárgy meglétének ellenőrzése
        /// ehhez meg kell adni a kérdéses tárgyat
        /// </summary>
        public bool targyLetezik(string targy)
        {
            N_1 komm = new N_1();
            komm.strings.Add("targy", targy);
            komm.bools.Add("letezik", false);

            komm = _pemsClient.targyLetezik(komm);
            return komm.bools["letezik"];
        }

        /// <summary>
        /// Kurzus meglétének ellenőrzése
        /// ehhez meg kell adni a kérdéses félévet és a kurzust
        /// </summary>
        public bool kurzusLetezik(string felev, string kurzus)
        {
            N_1 komm = new N_1();
            komm.strings.Add("felev", felev);
            komm.strings.Add("kurzus", kurzus);
            komm.bools.Add("letezik", false);

            komm = _pemsClient.kurzusLetezik(komm);
            return komm.bools["letezik"];
        }

        /// <summary>
        /// Vizsgaidőpont meglétének ellenőrzése
        /// ehhez meg kell adni a kérdéses félévet, kurzust és a vizsgaidőpontot
        /// </summary>
        public bool vizsgaLetezik(string felev, string kurzus, string vizsga)
        {
            N_1 komm = new N_1();
            komm.strings.Add("felev", felev);
            komm.strings.Add("kurzus", kurzus);
            komm.strings.Add("vizsga", vizsga);
            komm.bools.Add("letezik", false);

            komm = _pemsClient.vizsgaLetezik(komm);
            return komm.bools["letezik"];
        }

        /// <summary>
        /// Hallgató meglétének ellenőrzése
        /// ehhez meg kell adni a hallgatót
        /// </summary>
        public bool felhasznaloLetezik(string felhasznalo)
        {
            N_1 komm = new N_1();
            komm.strings.Add("felhasznalo", felhasznalo);
            komm.bools.Add("letezik", false);

            komm = _pemsClient.felhasznaloLetezik(komm);
            return komm.bools["letezik"];
        }

        /// <summary>
        /// Aktuális félév lekérdezése
        /// </summary>
        public string getAktualisFelev()
        {
            N_1 komm = new N_1();
            komm.strings.Add("felev", null);

            komm = _pemsClient.getAktualisFelev(komm);
            return komm.strings["felev"];
        }

        /// <summary>
        /// Vizsgára akar jelentkezni a hallgató
        /// ehhez meg kell adni a félévet, a kurzust és a vizsgaidőpontot
        /// </summary>
        public List<string> vizsgaJelentkezes(string hallgato, string felev, string kurzus, string vizsgaIdopontID)
        {

            N_1 komm = new N_1();
            komm.strings.Add("hallgato", hallgato);
            komm.strings.Add("felev", felev);
            komm.strings.Add("kurzus", kurzus);
            komm.strings.Add("vizsgaIdopontID", vizsgaIdopontID);

            komm = _pemsClient.vizsgaIdopontraFeliratkozas(komm);
            return komm.msg;
        }

        /// <summary>
        /// Félévek megjelenítése / összes illetve azon félévek listája ami(k)re beiratkozás történhet
        /// </summary>
        public List<string> getFelevLista(bool aktualis)
        {
            N_1 komm = new N_1();
            komm.bools.Add("aktualis", aktualis);
            komm = _pemsClient.getFelevLista(komm);
            return komm.row;
        }

        /// <summary>
        /// Félév hozzáadása
        /// id / megnevezés / kezdő dátum / vég dátum
        /// </summary>
        public bool felevHozzaadasa(string id, string megnevezes, DateTime kezdoDatum, DateTime vegDatum)
        {
            N_Datum komm = new N_Datum();
            komm.bools.Add("hozzaadva", false);
            komm.strings.Add("id", id);
            komm.strings.Add("megnevezes", megnevezes);
            komm.kezdoDatum = kezdoDatum;
            komm.vegDatum = vegDatum;
            komm = _pemsClient.felevHozzaadasa(komm);
            return komm.bools["hozzaadva"];
        }

        /// <summary>
        /// Felvehető vizsgákat akar látni a hallgató
        /// ehhez meg kell adni a félévet
        /// </summary>
        public List<string> getVizsgaIdopontok(string felev)
        {
            N_1 komm = new N_1();
            komm.strings.Add("felev", felev);
            komm = _pemsClient.getVizsgaIdopontList(komm);
            return komm.row;
        }

        /// <summary>
        /// Vizsgajelentkezéskor csak az aktuális kurzushoz tartozó időpontokat listázza a program
        /// ehhez meg kell adni a félévet és a kurzust
        /// </summary>
        public List<string> getVizsgaIdopontok(string felev, string kurzusid)
        {
            N_1 komm = new N_1();
            komm.strings.Add("felev", felev);
            komm.strings.Add("kurzus", kurzusid);
            komm = _pemsClient.getKurzusVizsgaIdopontList(komm);
            return komm.row;
        }
                
        /// <summary>
        /// Felvehető kurzusokat akar látni a hallgató
        /// ehhez meg kell adni a félévet
        /// </summary>
        public string getKurzusbyVizsgaidopontID(string felev, string vizsgaIdopontID)
        {
            N_1 komm = new N_1();
            komm.strings.Add("felev", felev);
            komm.strings.Add("kurzus", "");
            komm.strings.Add("vizsgaIdopontID", vizsgaIdopontID);
            komm = _pemsClient.getKurzusbyVizsgaidopontID(komm);
            return komm.strings["kurzus"];
        }

        /// <summary>
        /// Intézményi tárgyak listázása
        /// </summary>
        public List<string> getTargyLista()
        {
            N_1 komm = new N_1();
            komm = _pemsClient.getTargyList(komm);
            return komm.row;
        }

        /// <summary>
        /// Felvehető kurzusokat akar látni a hallgató
        /// ehhez meg kell adni a félévet
        /// </summary>
        public List<string> getKurzusLista(string felev, string userName)
        {
            N_1 komm = new N_1();
            komm.strings.Add("felev", felev);
            komm.strings.Add("userName", userName);
            komm = _pemsClient.getKurzusList(komm);
            return komm.row;
        }

        /// <summary>
        /// egy félév egy kurzusára akar felriratkozni egy hallgató
        /// ehhez meg kell adni a félév id-t és a kurzus id-t
        /// </summary>
        public List<string> kurzusJelentkezes(string hallgato, string felev, string kurzus)
        {
            N_1 komm = new N_1();
            komm.strings.Add("hallgato", hallgato);
            komm.strings.Add("felev", felev);
            komm.strings.Add("kurzus", kurzus);
            komm = _pemsClient.kurzusraFeliratkozik(komm);
            return komm.msg;
        }

        /// <summary>
        /// félévre akar beiratkozni a hallgató
        /// ehhez meg kell adni a félév id-t és a hallgató id-t
        /// </summary>
        public List<string> beiratkozasFelevre(string felev, string hallgato)
        {
            N_1 komm = new N_1();
            komm.strings.Add("felev", felev);
            komm.strings.Add("hallgato", hallgato);
            komm = _pemsClient.beiratkozasFelevre(komm);
            return komm.msg;
        }


        /// <summary>
        /// lekérdezi, hogy a hallgató felvette-e a kérdéses félévet
        /// ehhez meg kell adni a hallgatót és a félévet
        /// </summary>
        public List<string> getFelevFelveve(string felev, string hallgato)
        {
            N_1 komm = new N_1();
            komm.strings.Add("felev", felev);
            komm.strings.Add("hallgato", hallgato);
            komm.bools.Add("beiratkozott", false);
            komm.bools.Add("hiba", false);
            komm = _pemsClient.getFelevFelveve(komm);
//            return komm.bools["beiratkozott"];
            return komm.msg;
        }

        /// <summary>
        /// lekérdezi, hogy a hallgató felvette-e a kérdéses kurzust
        /// ehhez meg kell adni a hallgatót és a félévet és a kurzust
        /// </summary>
        public List<string> getKurzusFelveve(string felev, string kurzus, string hallgato)
        {
            N_1 komm = new N_1();
            komm.strings.Add("felev", felev);
            komm.strings.Add("kurzus", kurzus);
            komm.strings.Add("hallgato", hallgato);
            komm.bools.Add("felvette", false);
            komm.bools.Add("hiba", false);
            komm = _pemsClient.getKurzusFelveve(komm);
            return komm.msg;
        }

        /// <summary>
        /// lekérdezi, hogy a hallgató felvette-e a kérdéses kurzust
        /// ehhez meg kell adni a hallgatót és a félévet és a kurzust
        /// </summary>
        public List<string> getAlairasBeallitva(string felev, string kurzus, string hallgato)
        {
            N_1 komm = new N_1();
            komm.strings.Add("felev", felev);
            komm.strings.Add("kurzus", kurzus);
            komm.strings.Add("hallgato", hallgato);
            komm.bools.Add("alairva", false);
            komm.bools.Add("hiba", false);
            komm = _pemsClient.getAlairasBeallitva(komm);
            return komm.msg;
        }

        /// <summary>
        /// információk a felvett félévekről
        /// ehhez meg kell adni a hallgatót
        /// </summary>
        public List<string> getFelevInfo(string hallgato)
        {
            N_1 komm = new N_1();
            komm.strings.Add("hallgato", hallgato);
            komm = _pemsClient.getFelevInfo(komm);
            return komm.row;
        }        

        /// <summary>
        /// Felvett kurzusok lekérdezése
        /// Félév és hallgató megadásával
        /// </summary>
        public List<string> getFelvettKurzus(string felev, string hallgato)
        {
            N_1 komm = new N_1();
            komm.strings.Add("felev", felev);
            komm.strings.Add("hallgato", hallgato);
            komm = _pemsClient.getFelvettKurzus(komm);
            return komm.row;
        }

        /// <summary>
        /// Felvett vizsgák lekérdezése
        /// Félév és hallgató megadásával
        /// </summary>
        public List<string> getFelvettVizsga(string felev, string hallgato)
        {
            N_1 komm = new N_1();
            komm.strings.Add("felev", felev);
            komm.strings.Add("kurzus", "");
            komm.strings.Add("hallgato", hallgato);
            komm = _pemsClient.getFelvettVizsga(komm);
            return komm.row;
        }

        /// <summary>
        /// Felvett vizsga lekérdezése egy adott hallgatóra
        /// Félév, kurzus és hallgató megadásával
        /// </summary>
        public string getFelvettVizsga(string felev, string kurzus, string hallgato)
        {
            N_1 komm = new N_1();
            komm.strings.Add("felev", felev);
            komm.strings.Add("kurzus", kurzus);
            komm.strings.Add("hallgato", hallgato);
            komm.strings.Add("vizsgaidopontID", "");
            komm = _pemsClient.getFelvettVizsga(komm);
            return komm.strings["vizsgaidopontID"];
        }

        /// <summary>
        /// vizsgajegy ellenőrzése
        /// </summary>
        public List<string> vizsgajegyEllenorzes(string felev, string kurzus, string vizsgaidopontID, string hallgato)
        {
            N_1 komm = new N_1();
            komm.strings.Add("felev", felev);
            komm.strings.Add("kurzus", kurzus);
            komm.strings.Add("vizsgaidopontID", vizsgaidopontID);
            komm.strings.Add("hallgato", hallgato);
            komm.bools.Add("vizsgaJegyAdhato", true);

            komm = _pemsClient.vizsgajegyEllenorzes(komm);
            return komm.msg;
        }

        /// <summary>
        /// vizsgajegy beírása
        /// </summary>
        public List<string> VizsgaJegyBeiras(string felev, string kurzus, string vizsgaIdopontID, string hallgato, ErdemjegyEnum erdemjegy)
        {
            N_VizsgaJegyBeiras komm = new N_VizsgaJegyBeiras();
            komm.strings.Add("felev", felev);
            komm.strings.Add("kurzus", kurzus);
            komm.strings.Add("vizsgaIdopontID", vizsgaIdopontID);
            komm.strings.Add("hallgato", hallgato);
            komm.erdemjegy = erdemjegy;

            komm = _pemsClient.vizsgajegyBeiras(komm);
            return komm.msg;
        }

        /// <summary>
        /// Vizsgaeredmények lekérdezése
        /// Hallgató megadásával
        /// </summary>
        public List<string> getVizsgaEredmenyek(string felev, string hallgato)
        {
            N_1 komm = new N_1();
            komm.strings.Add("felev", felev);
            komm.strings.Add("hallgato", hallgato);
            komm = _pemsClient.getVizsgaEredmenyek(komm);
            return komm.row;
        }

        /// <summary>
        /// aláírás beállítása
        /// </summary>
        public List<string> alairasBeallitas(string felev, string kurzus, string hallgato, AlairasEnum alairasErtek)
        {
            N_AlairasBeallitas komm = new N_AlairasBeallitas();
            komm.strings.Add("felev", felev);
            komm.strings.Add("kurzus", kurzus);
            komm.strings.Add("hallgato", hallgato);
            komm.alairasErtek = alairasErtek;
            komm = _pemsClient.alairasBeallitas(komm);
            return komm.msg;
        }
    }
}
